/*
 * Jogo.java
 *
 * Created on 16 de Abril de 2007, 20:40
 */

package labirinto;

import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.MalformedURLException;
import java.net.URL;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.applet.*;

/**
 *
 * @author  tschimuneck
 */
public class Jogo extends javax.swing.JFrame implements Runnable {
    private Thing mapa[][],mapaOponentes[][],menuThings[] = new Thing[15];
    private boolean teclaDireita,teclaEsquerda,teclaCima,teclaBaixo,teclaAtirou;
    private JLabel lPersonA;
    private JLabel lPersonB;
    private Thing personA;
    private Thing personB;
    private JLabel mapaLabels[][];
    private Thread personThread;
    private int posXA,posYA;
    private int posXB,posYB;
    private int vidas;
    private boolean gameOver,paraDireira;
    private AudioClip somTiro;
    private int mapaAtual;
    
    /** Creates new form Jogo */
    public Jogo() {
        super("Jogo Labirinto");
        initComponents();
        this.setSize(640,480);
        this.setLayout(null);
        this.setDefaultCloseOperation(this.EXIT_ON_CLOSE);
        //paCenario.setLocation(this.getInsets().left,this.getInsets().top);
        paCenario.setSize(640,480);
        paCenario.setBackground(new Color(0,0,255));
        this.mapa = new Thing[20][15];
        this.mapaOponentes = new Thing[20][15];
        this.teclaBaixo = this.teclaDireita = this.teclaEsquerda = this.teclaCima = this.teclaAtirou = false;
        this.paraDireira = false;
        this.personA = new Thing();
        this.personA.setStopLeftIcon(new ImageIcon(this.getClass().getResource("/mario/stopLeft.gif")));
        this.personA.setStopRightIcon(new ImageIcon(this.getClass().getResource("/mario/stopRight.gif")));
        this.personB = new Thing();
        this.personB.setStopLeftIcon(new ImageIcon(this.getClass().getResource("/mario/stopLeft2.gif")));
        this.personB.setStopRightIcon(new ImageIcon(this.getClass().getResource("/mario/stopRight2.gif")));
        this.mapaLabels = new JLabel[20][15];
        //this.mapaLabels[0][14] = new JLabel();
        this.lPersonA = new JLabel();
        this.lPersonB = new JLabel();
        this.paCenario.add(this.lPersonA);
        this.lPersonA.setBounds(0,64,15,28);
        this.paCenario.add(this.lPersonB);
        this.lPersonB.setBounds(10,74,25,38);
        this.posXA = 128;
        this.posYA = 64;
        this.posXB = 128;
        this.posYB = 64;
        this.menuThings = new GenerateThings().generateThings();
        this.lbStatus.setLocation(10,this.paCenario.getX()+this.paCenario.getHeight());
        this.LeArquivoMapa("/mapa1.map");
        this.mapaAtual = 1;
        this.gameOver = false;
        this.vidas = 10;
        this.lbStatus.setText("Vidas: 10");
        try {
//        this.somTiro = Applet.newAudioClip(this.getClass().getResource("/tiro.wav"));
            this.somTiro = Applet.newAudioClip(new URL("file:///home/thiago/Desktop/Labirinto/resource/tiro.wav"));
            
        } catch (MalformedURLException ex) {
            ex.printStackTrace();
         }
    this.somTiro.stop();
    this.somTiro.play();
    this.personThread = new Thread(this);
    this.personThread.start();
 
}

public JPanel getPaCenario() {
    return this.paCenario;
}

public Thing[][] getMapa() {
    return this.mapa;
}

public Thing[][] getMapaOponentes() {
    return this.mapaOponentes;
}

/** This method is called from within the constructor to
 * initialize the form.
 * WARNING: Do NOT modify this code. The content of this method is
 * always regenerated by the Form Editor.
 */
    // <editor-fold defaultstate="collapsed" desc=" Generated Code ">//GEN-BEGIN:initComponents
    private void initComponents()
    {
        lbStatus = new javax.swing.JLabel();
        paCenario = new javax.swing.JPanel();

        getContentPane().setLayout(null);

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
        addKeyListener(new java.awt.event.KeyAdapter()
        {
            public void keyPressed(java.awt.event.KeyEvent evt)
            {
                formKeyPressed(evt);
            }
            public void keyReleased(java.awt.event.KeyEvent evt)
            {
                formKeyReleased(evt);
            }
        });

        lbStatus.setText("Vidas:");
        getContentPane().add(lbStatus);
        lbStatus.setBounds(20, 140, 370, 15);

        paCenario.setLayout(null);

        getContentPane().add(paCenario);
        paCenario.setBounds(30, 30, 150, 70);

        pack();
    }// </editor-fold>//GEN-END:initComponents
    
    private void formKeyReleased(java.awt.event.KeyEvent evt)//GEN-FIRST:event_formKeyReleased
    {//GEN-HEADEREND:event_formKeyReleased
// TODO adicione seu c�digo de manipula��o aqui:
        switch(evt.getKeyCode()) {
            case KeyEvent.VK_LEFT:
                this.teclaEsquerda = false;
                break;
            case KeyEvent.VK_RIGHT:
                this.teclaDireita = false;
                break;
            case KeyEvent.VK_UP:
                this.teclaCima = false;
                break;
            case KeyEvent.VK_DOWN:
                this.teclaBaixo = false;
                break;
        }
    }//GEN-LAST:event_formKeyReleased
    
    private void formKeyPressed(java.awt.event.KeyEvent evt)//GEN-FIRST:event_formKeyPressed
    {//GEN-HEADEREND:event_formKeyPressed
// TODO adicione seu c�digo de manipula��o aqui:
        switch(evt.getKeyCode()) {
            case KeyEvent.VK_LEFT:
                this.lPersonA.setIcon(this.personA.getStopLeftIcon());
                
                // ya ya ya
                this.lPersonB.setIcon(this.personB.getStopLeftIcon());
                
                this.teclaEsquerda = true;
                break;
            case KeyEvent.VK_RIGHT:
                this.lPersonA.setIcon(this.personA.getStopRightIcon());
                
                // ya ya ya
                this.lPersonB.setIcon(this.personB.getStopRightIcon());
                
                this.teclaDireita = true;
                break;
            case KeyEvent.VK_UP:
                this.teclaCima = true;
                break;
            case KeyEvent.VK_DOWN:
                this.teclaBaixo = true;
                break;
            case KeyEvent.VK_SPACE:
                this.teclaAtirou = true;
                break;
        }
        
    }//GEN-LAST:event_formKeyPressed
    
    private void colidiuEm(int x,int y) {
        if (this.mapa[x][y].getId() == 'B') {
            this.vidas += 3;
            this.lbStatus.setText("Vidas: "+this.vidas);
            this.mapa[x][y] = new Thing();
            this.paCenario.remove(this.mapaLabels[x][y]);
            this.paCenario.repaint();
        } else if (this.mapa[x][y].getId() == 'C') {
            if (this.vidas == 0) {
                this.gameOver = true;
                this.lbStatus.setText("GAME OVER!");
            } else {
                this.vidas--;
                this.lbStatus.setText("Vidas: "+this.vidas);
            }
            
        } else if (this.mapa[x][y].getId() == 'D') {
            this.mapaAtual++;
            for (int i = 0;i<20;i++) {
                for(int j=0;j<15;j++) {
                    if (this.mapaOponentes[i][j]!=null) {
                        this.mapaOponentes[i][j].getOponente().morre();
                    }
                    if (this.mapaLabels[i][j]!=null) {
                        this.paCenario.remove(this.mapaLabels[i][j]);
                    }
                }
            }
            //this.mapa = new Thing[20][15];
            //this.mapaOponentes = new Thing[20][15];
            //this.mapaLabels = new JLabel[20][15];
            LeArquivoMapa("/mapa"+this.mapaAtual+".map");
        }
        
    }
    
    public void run() {
        int offX=0,offY=0,offPulo=0,puloVel=0;
        boolean pulando=false,puloDirecao=true;
        while(!this.gameOver) {
            if (this.teclaDireita) {
                this.paraDireira = true;
                offX = (int)((this.posXA+this.lPersonA.getWidth()+4) / 32);
                
                // ya ya ya
                offX = (int)((this.posXA+this.lPersonB.getWidth()+4) / 32);
                
                
                offY = (int)((this.posYA-offPulo) / 32);
                if (offX >= 0 & offX < 20 & offY >= 0 & offY < 15) {
                    if (!this.mapa[offX][offY].getIsConcrete()) {
                        this.colidiuEm(offX,offY);
                        offY = (int)((this.posYA+this.lPersonA.getHeight()-3-offPulo) / 32);
                        
                        // ya ya ya
                        offY = (int)((this.posYA+this.lPersonB.getHeight()-3-offPulo) / 32);
                        
                        
                        if (offY >= 0 & offY < 15) {
                            if (!this.mapa[offX][offY].getIsConcrete()) {
                                this.colidiuEm(offX,offY);
                                this.posXA += 4;
                            }
                        }
                    }
                }
            }
            if (this.teclaEsquerda) {
                this.paraDireira = false;
                offX = (int)((this.posXA-4) / 32);
                offY = (int)((this.posYA-offPulo) / 32);
                if (offX >= 0 & offX < 20 & offY >= 0 & offY < 15 && this.posXA > 0) {
                    if (!this.mapa[offX][offY].getIsConcrete()) {
                        this.colidiuEm(offX,offY);
                        offY = (int)((this.posYA+this.lPersonA.getHeight()-3-offPulo) / 32);
                        
                        // ya ya ya
                        offY = (int)((this.posYA+this.lPersonB.getHeight()-3-offPulo) / 32);
                        
                        if (offY >= 0 & offY < 15) {
                            if (!this.mapa[offX][offY].getIsConcrete()) {
                                this.colidiuEm(offX,offY);
                                this.posXA -= 4;
                            }
                        }
                    }
                }
            }
            if (this.teclaBaixo || true) {
                offX = (int)(this.posXA / 32);
                offY = (int)((this.posYA+this.lPersonA.getHeight()) / 32);
                
                // ya ya ya
                offY = (int)((this.posYA+this.lPersonB.getHeight()) / 32);
                
                if (offY > 19) {
                    this.posYA = 32*19;
                }
                if (offX >= 0 & offX < 20 & offY >= 0 & offY < 15) {
                    if (!this.mapa[offX][offY].getIsConcrete()) {
                        this.colidiuEm(offX,offY);
                        offX = (int)((this.posXA+this.lPersonA.getWidth()) / 32);
                        
                        // ya ya ya
                        offX = (int)((this.posXA+this.lPersonB.getWidth()) / 32);
                        
                        if (offX >= 0 & offX < 20) {
                            if (!this.mapa[offX][offY].getIsConcrete()) {
                                this.colidiuEm(offX,offY);
                                this.posYA += 4;
                                this.teclaCima = false; // Impede de pular enquanto cai
                            }
                        }
                    }
                }
            }
            
            if (this.teclaCima) {
                if (!pulando) {
                    pulando=true;
                    puloVel=11;
                    puloDirecao = true;
                    offPulo=0;
                }
            }
            
            this.lPersonA.setLocation(this.posXA,this.posYA - offPulo);
            
            
            // ya ya ya
            this.lPersonB.setLocation(this.posXA,this.posYA - offPulo);
            
            
            /// Ver se esta pulando
            if (pulando) {
                if (puloDirecao) // Subindo
                {
                    offPulo += puloVel--;
                    if (puloVel == 0) {
                        puloDirecao = false; // Vai descer
                    }
                } else // Descendo
                {
                    offPulo -= puloVel++;
                    if (puloVel == 14) {
                        pulando = false; // Para de pular
                        offPulo = 0;
                    }
                }
                // Testar se n�o bateu debaixo de uma pe�a
                if (puloDirecao) // Somente se subindo
                {
                    offX = (int)(this.posXA / 32);
                    offY = (int)((this.posYA-offPulo) / 32);
                    if (offX >= 0 & offX < 20 & offY >= 0 & offY < 15 & this.posYA > 0) {
                        if (this.mapa[offX][offY].getIsConcrete()) {
                            puloDirecao = false; // Descer
                        } else {
                            this.colidiuEm(offX,offY);
                            offX = (int)((this.posXA+this.lPersonA.getWidth()) / 32);
                            
                            // ya ya ya
                            offX = (int)((this.posXA+this.lPersonB.getWidth()) / 32);
                            
                            if (offX >= 0 & offX < 20) {
                                if (this.mapa[offX][offY].getIsConcrete()) {
                                    puloDirecao = false;
                                } else {
                                    this.colidiuEm(offX,offY);
                                }
                            }
                        }
                    }
                } else {
                    // Verificar se n�o bateu algo debaixo dos p�s
                    offX = (int)(this.posXA / 32);
                    offY = (int)((this.posYA+this.lPersonA.getHeight()-offPulo-1) / 32);
                    
                    // ya ya ya
                    offY = (int)((this.posYA+this.lPersonB.getHeight()-offPulo-1) / 32);
                    
                    if (offX >= 0 & offX < 20 & offY >= 0 & offY < 15) {
                        if (!this.mapa[offX][offY].getIsConcrete()) {
                            offX = (int)((this.posXA+this.lPersonA.getWidth()) / 32);
                            
                            // ya ya ya
                            offX = (int)((this.posXA+this.lPersonB.getWidth()) / 32);
                            
                            if (offX > 0 & offX < 20) {
                                if (this.mapa[offX][offY].getIsConcrete()) {
                                    pulando=false;
                                    this.posYA = (offY-1)*32;
                                    offPulo=0;
                                } else {
                                    this.colidiuEm(offX,offY);
                                }
                            }
                        } else {
                            this.colidiuEm(offX,offY);
                            pulando=false;
                            this.posYA = (offY-1)*32;
                            offPulo=0;
                        }
                    }
                }
            }
            if (this.teclaAtirou) {
                this.teclaAtirou = false;
                Bala b = new Bala(this);
                b.setPosX(this.posXA);
                b.setPosY(this.posYA - offPulo + 6);
                b.setVelX( this.paraDireira ? 10 : -10 );
                b.dispara();
                this.somTiro.play();
            }
            this.lPersonA.setLocation(this.posXA,this.posYA - offPulo);
            
            // ya ya ya
            this.lPersonB.setLocation(this.posXA,this.posYA - offPulo);
            
            
            try {
                Thread.sleep(30);} catch(Exception e) {
                }
        }
    }
    
    private boolean LeArquivoMapa(String nome) {
        BufferedReader bfArquivo = null;
        boolean result = true;
        try {
            //bfArquivo = new BufferedReader(new FileReader(nome));
            URL resource = getClass().getResource(nome);
            bfArquivo = new BufferedReader(new InputStreamReader(resource.openStream()));
            String sLinha = null;
            int j = 0; // Linha
            while ((sLinha=bfArquivo.readLine())!=null) {
                for (int i=0;i<sLinha.length();i++) {
                    for(int k=0;k<this.menuThings.length;k++) {
                        Thing t = this.menuThings[k];
                        if (t==null) {
                            continue;
                        }
                        if (sLinha.charAt(i) == 'P') {
                            if (this.mapaLabels[i][j] != null) {
                                this.paCenario.remove(this.mapaLabels[i][j]);
                            }
                            
                            // ya ya ya [ segunda linha ]
                            this.personA = this.mapa[i][j] = new Thing();
                            this.personB = this.mapa[i][j] = new Thing();
                            
                            this.personA.setId('P');
                            this.personB.setId('P');
                            
                            this.personA.setStopLeftIcon(new ImageIcon(this.getClass().getResource("/mario/stopLeft.gif")));
                            this.personB.setStopLeftIcon(new ImageIcon(this.getClass().getResource("/mario/stopLeft.gif")));
                            
                            this.personA.setStopRightIcon(new ImageIcon(this.getClass().getResource("/mario/stopRight.gif")));
                            this.personB.setStopRightIcon(new ImageIcon(this.getClass().getResource("/mario/stopRight.gif")));
                            
                            this.lPersonA.setBounds(32*i,32*j,15,28);
                            this.lPersonB.setBounds(32*i,32*j,15,28);
                            
                            this.posXA = 32*i;
                            this.posYA = 32*j;
                            
                            lPersonB.setIcon(this.personB.getStopLeftIcon());
                            lPersonB.setIcon(this.personB.getStopLeftIcon());
                            
                            
                            break;
                        }
                        if (sLinha.charAt(i) == '2') {
                            if (this.mapaLabels[i][j] != null) {
                                this.paCenario.remove(this.mapaLabels[i][j]);
                            }
                            this.personB = this.mapa[i][j] = new Thing();
                            this.personB.setId('P');
                            this.personB.setStopLeftIcon(new ImageIcon(this.getClass().getResource("/mario/stopLeft2.gif")));
                            this.personB.setStopRightIcon(new ImageIcon(this.getClass().getResource("/mario/stopRight2.gif")));
                            this.lPersonB.setBounds(32*i,32*j,15,28);
                            this.posXB = 32*i;
                            this.posYB = 32*j;
                            lPersonB.setIcon(this.personB.getStopLeftIcon());
                            break;
                        } else if (t.getId() == sLinha.charAt(i)) {
                            Thing tgNovaPeca = this.mapa[i][j] = t.clone();
                            if (sLinha.charAt(i) == 'E') {
                                tgNovaPeca.setIsOpponent(true);
                                Tartaruga tar = new Tartaruga(this);
                                tgNovaPeca.setOponente(tar);
                                tar.setPosX(i*32);
                                tar.setPosY(j*32);
                                tar.setThing(tgNovaPeca);
                                tar.vive();
                            } else {
                                JLabel g = new JLabel();
                                g.setIcon(tgNovaPeca.getStopLeftIcon());
                                g.setSize(32,32);
                                if (this.mapaLabels[i][j] != null) {
                                    this.paCenario.remove(this.mapaLabels[i][j]);
                                }
                                this.mapaLabels[i][j] = g;
                                this.paCenario.add(g);
                                g.setLocation(i*32,j*32);
                            }
                            break;
                        } else {
                            this.mapa[i][j] = new Thing();
                            if (this.mapaLabels[i][j] != null) {
                                this.paCenario.remove(this.mapaLabels[i][j]);
                            }
                        }
                    }
                }
                j++;
            }
        } catch (FileNotFoundException ex) {
            ex.printStackTrace();
            result=false;
        } catch (IOException ex) {
            ex.printStackTrace();
            result=false;
        } finally {
            try {
                if (bfArquivo!= null) {
                    bfArquivo.close();
                }
            } catch (IOException ex) {
                ex.printStackTrace();
                result=false;
            }
        }
        this.paCenario.repaint();
        return result;
    }
    
    /**
     * @param args the command line arguments
     */
    
    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JLabel lbStatus;
    private javax.swing.JPanel paCenario;
    // End of variables declaration//GEN-END:variables
    
}
